﻿using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Text;

namespace PowerCalculation
{
    public class ElectricsRepository
    {  
        private ElectronicsDataBaseEntities1 _entities;
        public ElectricsRepository(ElectronicsDataBaseEntities1 entities)
        {
            _entities = entities;
        }
        public Lamp GetLamp(int id)
        {
            return _entities.Lamp.Where(l => l.LampId == id).FirstOrDefault();
        }
        public Electronics GetElectronics(int id)
        {
            return _entities.Electronics.Where(l => l.ElectronicsId == id).FirstOrDefault();
        }

        public IEnumerable<EntityObject> GetAllElectrics()
        {
            var entityObjects = new List<EntityObject>();
            entityObjects.AddRange(_entities.Lamp.ToList());
            entityObjects.AddRange(_entities.Electronics.ToList());
            return entityObjects;
        }

        public Automat GetAutomatByPower(float power)
        {
            var allowableAutomat = _entities.Automat.Where(automat => automat.AutomatPower >= power).Count();
            return allowableAutomat != 0 ? _entities.Automat.Where(automat => automat.AutomatPower >= power).First() : null;
        }

        public IEnumerable<Automat> GetAutomats()
        {
            return _entities.Automat.ToList();
        }

        public IEnumerable<Material> GetMaterials()
        {
            return _entities.Material.ToList();
        }

        public IEnumerable<Section> GetSections()
        {
            return _entities.Section.ToList();
        }

        public IEnumerable<Section> GetSectionsByMaterialId(int matId)
        {
            List<int?> list = _entities.Wire.Where(wire => wire.WireMaterialId == matId).Select(wire => wire.WireSectionId).ToList();
            return _entities.Section.Where(sect=>list.Contains(sect.SectionId)); 
        }

        public IEnumerable<Wire> GetWires()
        {
            return _entities.Wire.ToList();
        }

        public IEnumerable<Lamp> GetLamps()
        {
            return GetAllElectrics().Where(n => n is Lamp).Cast<Lamp>();
        }

        public IEnumerable<Electronics> GetElectronics()
        {
            return GetAllElectrics().Where(n => n is Electronics).Cast<Electronics>();
        }

        public float?  GetReglamentAmperage(int consumerId)
        {
            Electronics consumer =  _entities.Electronics.Single(cons => cons.ElectronicsId == consumerId);
            var reglamentConsumerWireId = consumer.ElectronicsReglamentWireId;
            if(reglamentConsumerWireId == null)
            {
                return null;
            }
            return (float)_entities.Wire.Single(wire => wire.WireId == reglamentConsumerWireId).WireAmperage;
        }

        public int? GetReglamentWireId(int consumerId)
        {
            return _entities.Electronics.Single(consumer => consumer.ElectronicsId == consumerId).ElectronicsReglamentWireId;
        }


        public float GetWireAmperage(int materialId, int sectionId, int coreCount)
        {
            return
                (float)
                _entities.Wire.Single(
                    wire =>
                    wire.WireMaterialId == materialId && wire.WireSectionId == sectionId &&
                    wire.WireCoreCount == coreCount).WireAmperage;

        }

        public void AddLamp(float power, string description)
        {
            _entities.AddToLamp(new Lamp() { LampId = _entities.Lamp.NextId(n => n.LampId), LampPower = power, LampDescription = description });
            _entities.SaveChanges();
        }

        public void AddElectronics(float power, string description)
        {
            _entities.AddToElectronics(new Electronics() { ElectronicsId = _entities.Electronics.NextId(n => n.ElectronicsId), ElectronicsPower = power, ElectronicsDescription = description });
            _entities.SaveChanges();
        }

        public void AddAutomat(float automatAmperage, string automatDescription)
        {
            _entities.AddToAutomat(new Automat()
            {
                AutomatId = _entities.Automat.NextId(n => n.AutomatId),
                AutomateAmperage = automatAmperage,
                AutomatDescription = automatDescription
            });
            _entities.SaveChanges();
        }

        public void AddMaterial(string value)
        {
            _entities.AddToMaterial(new Material()
                                        {
                                            MaterialId = _entities.Material.NextId(n => n.MaterialId),
                                            MaterialName = value
            });
            _entities.SaveChanges();
        }

        public void AddWire(Material wireMaterial, Section wireSection)
        {
            _entities.Wire.AddObject(new Wire()
                                         {
                                             WireMaterialId = _entities.Wire.NextId(n => n.WireMaterialId),
                                             Material = wireMaterial,
                                             Section = wireSection
                                         });
            _entities.SaveChanges();
        }

        public void AddSection(float value)
        {
            _entities.Section.AddObject(new Section()
            {
                SectionId = _entities.Section.NextId(n => n.SectionId),
                SectionValue = value
            });
            _entities.SaveChanges();
        }



        public bool IsEmpty()
        {
            return _entities.Automat.Count() == 0
                   & _entities.Section.Count() == 0
                   & _entities.Wire.Count() == 0
                   & _entities.Material.Count() == 0
                   & _entities.Lamp.Count() == 0
                   & _entities.Electronics.Count() == 0;
        }
    }
}
